package ru.sgu.diploma.practic.service.impl;

import ru.sgu.diploma.practic.domain.model.GeometricModel;
import ru.sgu.diploma.practic.domain.model.ImageResolution;
import ru.sgu.diploma.practic.service.ImageConstructor;

import java.awt.*;

import ru.sgu.diploma.practic.domain.model.Point;

import java.awt.image.BufferedImage;

/**
 * User: datmakin
 * Date: 13.03.11
 * Time: 20:25
 */
public class ImageConstructorImpl implements ImageConstructor {

    private Integer backgroundColor = 0x000000;
    private Integer cellColor = 0xFFFFFF;
    private Integer color = 0xAAFFAA;
    private Integer centerColorMerge = 0xFFAAFF;

    private Integer cellStep = 10;
    private Integer cellSize = 2;

    private Component component = new Canvas();

    public BufferedImage constructWithScale(GeometricModel geometricModel, Integer k) {
        ImageResolution ir = geometricModel.getImageResolution();
        BufferedImage bufferedImage = new BufferedImage(ir.getWidth() * k, ir.getHeight() * k, 1);

        bufferedImage = drawBackground(bufferedImage);
        bufferedImage = drawLines(bufferedImage, ir.getWidth(), ir.getHeight(), ir.getBegin(), k);

        // draw each point from model
        for (Point point : geometricModel.getPointList()) {
            Integer prColor = color;
            if (ir.getBegin().getX().equals(ir.getBegin().getX() + point.getX()) ||
                    ir.getBegin().getY().equals(ir.getBegin().getY() + point.getY()))
                prColor = centerColorMerge;

            // scale according to k
            for (int i = 0; i < k; i++)
                for (int j = 0; j < k; j++)
                    bufferedImage.setRGB(ir.getBegin().getX() * k + point.getX() * k + i,
                            ir.getBegin().getY() * k + point.getY() * k + j,
                            prColor);
        }

        return bufferedImage;
    }

    private BufferedImage drawBackground(BufferedImage bufferedImage) {

        for (int x = 0; x < bufferedImage.getWidth(); x++)
            for (int y = 0; y < bufferedImage.getHeight(); y++)
                bufferedImage.setRGB(x, y, backgroundColor);

        return bufferedImage;
    }

    private BufferedImage drawLines(BufferedImage bufferedImage, Integer width, Integer height, Point center, Integer k) {
        for (int y = 0; y < height * k - k; y++) {
            int x = center.getX() * k;
            for (int i = 0; i < k; i++)
                for (int j = 0; j < k; j++)
                    bufferedImage.setRGB(x + i, y + j, cellColor);

            if (y % (cellStep * k) == 0) {
                for (int xi = x - (cellSize * k); xi < x + ((cellSize * k) + 1); xi++) {
                    for (int i = 0; i < k; i++)
                        for (int j = 0; j < k; j++)
                            bufferedImage.setRGB(xi + i, y + j, cellColor);
                }
            }
        }

        for (int x = 0; x < width * k - k; x++) {
            int y = center.getY() * k;
            for (int i = 0; i < k; i++)
                for (int j = 0; j < k; j++)
                    bufferedImage.setRGB(x + i, y + j, cellColor);
            if (x % (cellStep * k) == 0) {
                for (int yi = y - (cellSize * k); yi < y + ((cellSize * k) + 1); yi++) {
                    for (int i = 0; i < k; i++)
                        for (int j = 0; j < k; j++)
                            bufferedImage.setRGB(x + i, yi + j, cellColor);
                }
            }
        }
        return bufferedImage;
    }

    public BufferedImage construct(GeometricModel geometricModel) {
        return constructWithScale(geometricModel, 1);
    }
}
